package com.ease.integration.service.impl;

import java.lang.reflect.Method;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.ease.common.util.Assertion;
import com.ease.common.util.Detect;
import com.ease.integration.service.ExternalServiceDispatcher;
import com.ease.integration.service.IntegrationService;

public class ExternalServiceDispatcherImpl implements ExternalServiceDispatcher {

	private static final transient Log log = LogFactory.getLog(ExternalServiceDispatcherImpl.class);

	private Map<String, IntegrationService> integrationServices;

	private ExternalServiceDispatcher remoteExternalServiceDispatcher;

	public Map<String, Object> doService(String classReferenceKeyName, String beanMethodName, String serviceKey, String externalServiceName, Map<String, Object> requestMap) {
		// if (null != IntegrationLogContext.getIntegrationLogContext() && null
		// !=
		// IntegrationLogContext.getIntegrationLogContext().getIntegrationLog())
		// {
		// IntegrationLog integrationLog =
		// IntegrationLogContext.getIntegrationLogContext().getIntegrationLog();
		// integrationLog.setServiceKey(serviceKey);
		// }

		if (null != remoteExternalServiceDispatcher) {
			return this.doRemoteService(classReferenceKeyName, beanMethodName, serviceKey, externalServiceName, requestMap);
		} else {
			return this.doLocalService(classReferenceKeyName, beanMethodName, serviceKey, externalServiceName, requestMap);
		}
	}

	public Map<String, Object> doRemoteService(String classReferenceKeyName, String beanMethodName, String serviceKey, String externalServiceName, Map<String, Object> requestMap) {
		return remoteExternalServiceDispatcher.doService(classReferenceKeyName, beanMethodName, serviceKey, externalServiceName, requestMap);
	}

	protected Map<String, Object> doLocalService(String classReferenceKeyName, String beanMethodName, String serviceKey, String externalServiceName, Map<String, Object> requestMap) {
		/* 根据context得到service的客户端 */
		IntegrationService integrationService = integrationServices.get(classReferenceKeyName);
		Assertion.notNull(integrationService, classReferenceKeyName + "无对应类对象");

		if (log.isDebugEnabled()) {
			StringBuffer sb = new StringBuffer();
			sb.append("接口输出信息:\r\nclassReferenceKey.method: " + classReferenceKeyName + "." + beanMethodName + "\r\n");
			for (Map.Entry<String, Object> entry : requestMap.entrySet()) {
				sb.append("arg[" + entry.getKey() + "]: " + entry.getValue() + "\r\n");
			}
			log.debug(sb.toString());
		}
		Map<String, Object> responseArguments = null;
		try {
			Method method = integrationService.getClass().getDeclaredMethod(beanMethodName, new Class[] { String.class, Map.class });
			Object resp = method.invoke(integrationService, new Object[] { externalServiceName, requestMap });
			responseArguments = (Map<String, Object>) resp;
		} catch (Exception e) {
			log.error(e, e);

			// if (null != IntegrationLogContext.getIntegrationLogContext()) {
			// IntegrationLog integrationLog =
			// IntegrationLogContext.getIntegrationLogContext
			// ().getIntegrationLog();
			// if (null != integrationLog) {
			// integrationLog.setIntegrationResult(IntegrationResultType.Failure)
			// ;
			// integrationLog.setErrorMessage(e.getMessage());
			// }
			// }
		}

		if (log.isDebugEnabled()) {
			StringBuffer sb = new StringBuffer();
			sb.append("接口返回信息:\r\nclassReferenceKey.method: " + classReferenceKeyName + "." + beanMethodName + "\r\n");
			if (Detect.notEmpty(responseArguments)) {
				for (Map.Entry<String, Object> entry : responseArguments.entrySet()) {
					sb.append("arg[" + entry.getKey() + "]: " + entry.getValue() + "\r\n");
				}
			} else {
				sb.append("接口返回信息为空:\r\nclassReferenceKey.method: " + classReferenceKeyName + "." + beanMethodName + "\r\n");
			}
			log.debug(sb.toString());
		}
		return responseArguments;
	}

	public Map<String, IntegrationService> getIntegrationServices() {
		return integrationServices;
	}

	public void setIntegrationServices(Map<String, IntegrationService> integrationServices) {
		this.integrationServices = integrationServices;
	}

	public ExternalServiceDispatcher getRemoteExternalServiceDispatcher() {
		return remoteExternalServiceDispatcher;
	}

	public void setRemoteExternalServiceDispatcher(ExternalServiceDispatcher remoteExternalServiceDispatcher) {
		this.remoteExternalServiceDispatcher = remoteExternalServiceDispatcher;
	}

}
